<?php

namespace App\Kuafu\Guanyuan\Command;

use App\Kuafu\Base\Command\Traits\KfGetTimeInterval;
use App\Kuafu\Base\Model\BaseModel;
use App\Kuafu\Category\Model\CategoryModel;
use App\Kuafu\Common\Service\CommonService;
use App\Kuafu\Guanyuan\Enum\DishDetailEnum;
use App\Kuafu\Guanyuan\Model\DishDetailCHModel;
use App\Kuafu\Guanyuan\Model\DishDetailModel;
use App\Kuafu\Order\Enum\CodeEnum;
use App\Kuafu\Order\Model\OrderCouponSplitModel;
use App\Kuafu\Order\Model\OrderDetailSplitModel;
use App\Kuafu\Order\Model\OrderSplitModel;
use App\Kuafu\Shop\Model\Shop;
use App\Library\FeiShu\SendFs;
use App\Library\SnowFlake\SnowFlake;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;

class OrderDishDetailV2Command extends Command
{
    protected $signature = 'guanyuan:kfSyncDishDetailV2 {startDate} {endDate} {shopIds?}';

    protected $description = '观远订单同步:堂食菜品数据';

    private array $skipShopIds = [
        13315
    ];

    public function handle()
    {
        // qa 环境关闭运行
        if (isTest()) {
            return false;
        }

        ini_set('memory_limit', '2048M');

        $startDate = $this->argument('startDate');
        $endDate   = $this->argument('endDate');


        $this->info(vsprintf("夸父堂跑批入观远数据库开始: %s 00:00:00 至 %s 00:00:00 ", [$startDate, $endDate]));

        $manualShopIds = $this->argument('shopIds');

        $tmpMsg = $manualShopIds ? '是' : '否';

        $this->info(vsprintf('检查是否指定门店: %s', [$tmpMsg]));

        // 获取所有店铺信息

        $shopList = self::getAllShop([
            'name',
            'id',
            'addressPrefix',
            'shopCode',
            'province',
            'city',
            'district'
        ]);


        $inShopList = $shopList
            ->when($manualShopIds, function ($query) use ($manualShopIds) {
                $manualShopIds = explode(",", $manualShopIds);
                return $query->whereIn('id', $manualShopIds);
            })
            ->whereNotIn('id', $this->skipShopIds)
            ->where('id', '>', 19)
//            ->where('status', \App\Kuafu\Shop\Enum\CodeEnum::SHOP_STATUS_NORMAL)
            ->where('shopCode', '<', 8000);

        $resultFs    = [];
        $queryDate   = [];
        $endTimeAt   = strtotime($endDate);
        $startTimeAt = strtotime($startDate);
        $diff        = ($endTimeAt - $startTimeAt) / 86400;
        for ($d = 1; $d <= $diff; $d++) {
            $queryDate[] = [
                'startTime' => $startTimeAt + 86400 * ($d - 1),
                'endTime'   => $startTimeAt + 86400 * $d
            ];
        }

        foreach ($queryDate as $date) {

            $totalAll = 0;
            $this->error(vsprintf(PHP_EOL . '开始获取 %s 00:00:00 ~ %s 00:00:00 内的门店数据, 并开始循环门店', [
                date('Y-m-d', $date['startTime']),
                date('Y-m-d', $date['endTime']),
            ]));


            foreach ($inShopList as $shopInfo) {

                // 判断是否数据库中有数据如果有数据 则 不删除
                $shopId = $shopInfo->id;
                $order  = OrderSplitModel::suffix($shopId)
                                         ->query()
                                         ->whereBetween('createdAt', [$date['startTime'], $date['endTime']])
                                         ->when($manualShopIds, function ($query) use ($manualShopIds) {
                                             $manualShopIds = explode(",", $manualShopIds);
                                             $query->whereIn('shopId', $manualShopIds);
                                         })
                                         ->where('shopId', $shopId)
                                         ->where('payStatus', CodeEnum::ORDER_PAY_STATUS_PAYED)
                                         ->whereIn('orderStatus', [CodeEnum::ORDER_STATUS_FINISHED])
                                         ->where('isDeleted', BaseModel::DELETE_NO)
                                         ->get();

                $this->info(vsprintf("%s 门店共有 %s 条订单记录代处理",
                    [$shopInfo->shopCode . $shopInfo->name, $order->count()]));

                if (!$order->count()) {
                    continue;
                }

                $totalAll += $order->count();

                // 删除数据
                DishDetailModel::query()
                               ->where('checkoutTime', '>=', date('Y-m-d H:i:s', $date['startTime']))
                               ->where('checkoutTime', '<=', date('Y-m-d H:i:s', $date['endTime']))
                               ->where('source', DishDetailEnum::SOURCE_KUAFU)
                               ->where("poiName", "like",
                                   CommonService::zeroFill($shopList[$shopId]['shopCode']) . "%")
                               ->delete();

                $this->info(vsprintf("%s 门店的观远堂食数据已删除", [$shopInfo->shopCode . $shopInfo->name]));

                // 获取所有原订单数据

                $order->chunk(100)->each(function ($orderChunk) use ($shopId, $inShopList) {
                    $orderIds      = $orderChunk->pluck('orderId');
                    $orderListById = $orderChunk->keyBy('orderId');

                    // 获取所有原订单菜品详情

                    $orderDetail = OrderDetailSplitModel::suffix($shopId)
                                                        ->query()
                                                        ->whereIn('orderId', $orderIds)
                                                        ->where('refundNum', 0)
                                                        ->where('isDeleted', 0)
                                                        ->where('packageId', 0)
                                                        ->get();

                    $orderCouponList = OrderCouponSplitModel::suffix($shopId)
                                                            ->query()
                                                            ->whereIn('orderId', $orderIds)
                                                            ->where('isDeleted', 0)
                                                            ->get();

                    $insertData = [];

                    foreach ($orderDetail as $detail) {
                        $orderInfo = $orderListById[$detail['orderId']];

                        $insert = [
                            'id'             => SnowFlake::nextId(random_int(1, 32), random_int(1, 32)),
                            'province'       => $inShopList[$detail['shopId']]['province'],
                            'city'           => $inShopList[$detail['shopId']]['city'],
                            'district'       => $inShopList[$detail['shopId']]['district'],
                            'poiName'        => CommonService::zeroFill($inShopList[$detail['shopId']]['shopCode']) . $inShopList[$detail['shopId']]['name'],
                            'spuId'          => $detail['productId'],
                            'spuName'        => $detail['productName'],
                            'specs'          => '',
                            'unit'           => $detail['unit'],
                            'firstCateName'  => $this->getCategoryName($detail['categoryId']),
                            'orderNo'        => $detail['orderId'],
                            'orderId'        => $detail['orderId'],
                            'count'          => $detail['num'],
                            'totalPrice'     => $detail['originalPrice'] / 100,
                            'discountAmount' => ($detail['totalDiscountPrice'] - $detail['couponCostPrice']) / 100,
                            'taxExcludedAmt' => ($detail['payPrice'] + $detail['couponCostPrice']) / 100,
                            'goodsTime'      => $detail['createdAt'],
                            'orderTime'      => $orderInfo['createdAt'],
                            'checkoutTime'   => date('Y-m-d H:i:s', $orderInfo['completeTime']),
                            'categoryName'   => '店内销售',
                            'sourceName'     => $this->switchSourceName($orderInfo['sourceType']),
                            // 小程序等
                            'orderPrice'     => $orderInfo['originalPrice'] / 100,
                            //订单原价
                            'orderDiscount'  => ($orderInfo['discountPrice'] - $orderInfo['couponCostPrice']) / 100,
                            //订单优惠
                            'orderIncome'    => ($orderInfo['payPrice'] + $orderInfo['couponCostPrice']) / 100,
                            // 订单实收
                            'flagName'       => '',
                            'createdAt'      => date('Y-m-d H:i:s'),
                            'updatedAt'      => date('Y-m-d H:i:s'),
                            'discountName'   => '',
                            'source'         => 1,
                            'dataFrom'       => 'kuafu',
                        ];

                        // 如果有订单优惠 去查订单优惠表记录
                        $discountName = '';
                        if ($insert['orderDiscount'] > 0) {
                            $discountName = '';

                            // 先看订单是否是试吃
                            if ($orderInfo['payChannel'] == CodeEnum::ORDER_PAY_CHANNEL_TRY_TACK) {
                                $discountName .= '自定义记账-试吃(自),';
                            }

                            // 是否赠菜
                            if ($detail['freeNum'] > 0) {
                                $discountName .= '自定义记账-赠菜(自),';
                            }

                            // 是否减免
                            if ($detail['discountType'] > 0) {
                                $discountName .= '自定义记账-' . CodeEnum::DISCOUNT_TYPE_TEXT[$detail['discountType']] . '(自),';
                            }

                            // 循环获取优惠券信息
                            foreach ($orderCouponList as $orderCoupon) {
                                if ($orderCoupon['orderId'] == $detail['orderId']) {
                                    $discountName .= '优惠券-' . $orderCoupon['couponName'] . ';';
                                }
                            }
                            $discountName = trim($discountName, ',');
                        }
                        $insert['discountName'] = $discountName;
                        $insertData[]           = $insert;
                    }

                    collect($insertData)->chunk(1000)->each(function ($item) {
                        try {
                            $insertData = $item->toArray();
                            $insertData = array_values($insertData);
//                            dump($insertData);
                            DishDetailModel::query()->insert($insertData);
                        } catch (\Exception $exception) {
                            dd($exception);
                            self::sendFs('Clickhouse 写入数据异常', ['3fgc8798']);
                        }
                    });

                });

            }

            $this->error(vsprintf('本日共 %s 条记录', [$totalAll]));

        }

        // 组装飞书数据
        $content = date('Y-m-d H:i:s',
                $startTimeAt) . ' 至 ' . date('Y-m-d H:i:s',
                $endTimeAt - 1) . ' 数据已经入库至观远, 耗时' . bcdiv(microtime(true) - LARAVEL_START, 60, 2) . '分钟';

        self::sendFs($content);
        return;
    }

    public static $allCategory = null;

    private function getAllCategory()
    {
        if (!self::$allCategory) {
            self::$allCategory = CategoryModel::query()->select(['id', 'pid', 'name'])->get()->keyBy('id')->toArray();
        }
        return self::$allCategory;
    }

    private function getCategoryName($id)
    {
        $list = $this->getAllCategory();
        if (key_exists($id, $list)) {
            return $list[$id]['name'];
        } else {
            return '';
        }
    }

    private function switchSourceName($sourceType)
    {
        switch ($sourceType) {
            case 1:
                return '收银POS';
            case 2:
                return '小程序';
            default:
                return '';
        }
    }

    private static function sendFs($content, $fsUid = [])
    {
        if (!empty($content)) {
            SendFs::newRobot(SendFs::ROBOT_GUANYUAN)
                  ->setTitleContent('[堂食] ' . date('Y-m-d H:i:s', time()), $content)
                  ->setAtUids($fsUid)
                  ->send();
        }
    }

    public function infoTime(string $tag)
    {
        $this->info($tag . ' : ' . (microtime(true) - LARAVEL_START));
    }

    private function getAllShop(array $field)
    {
        return Shop::query()
                   ->select($field)
//                   ->where('id', 13112)
//                   ->limit(10)
                   ->get()
                   ->keyBy('id')
                   ->each(function ($item) {
                       // 处理省市区
                       $ssq = explode('-', $item['addressPrefix']);
                       if (empty($ssq)
                           || empty($ssq[0])
                           || empty($ssq[1])
                           || empty($ssq[2])
                       ) {
                           return;
                       }

                       $item['province'] = $ssq[0];
                       $item['city']     = $ssq[1];
                       $item['district'] = $ssq[2];
                   });
    }
}
